import os
from os.path import isdir
import re
import requests
from lxml import etree
from concurrent.futures import ThreadPoolExecutor, wait

tasks = []
music_dir = "music.d"
key_ignore = ["伴奏", "DJ", "Remix", "Live"]
key_is_exist = []

def get_html_obj(url, method="get"):
    """TODO: Docstring for get_html_obj.

    :arg1: TODO
    :returns: TODO

    """
    resp_text = ""
    if method == "get":
        resp_text = requests.get(url=url).text
    else:
        raise Exception("error: method is error")
    html = etree.HTML(resp_text)
    return html


def get_xpath_list(html_obj, xpath_patten):
    # //div[@class='row']
    ret = html_obj.xpath(xpath_patten)
    if not ret:
        # for i in ret:
        #     print(i)
        return None
    return ret


def get_post(url, data, headers={}, type_return="json"):
    if type_return == "json":
        resp = requests.post(url, data, headers=headers).json()
    else:
        resp = requests.post(url, data, headers=headers).text
    return resp


def get_music_url(mid):
    """
    通过id获取歌曲的地址
    """
    url = "https://www.fangpi.net/api/play-url"
    data = f"id={mid}"
    resp_json = get_post(url, data=data, headers={"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}, type_return="json")
    return resp_json.get("data").get("url")


def get_music_mid(m_url):
    """TODO: Docstring for get_music_id.

    :m_url: TODO
    :returns: TODO

    """
    print(f"m_url: {m_url}")
    resp = requests.get(m_url).text
    patten_str = "window.play_id = '(?P<mid>.*?)';"
    patten = re.compile(patten_str, re.S)
    it = patten.finditer(resp)
    for i in it:
        # print(i.group("mid"))
        return i.group("mid")
    return None

def download(local_filename, url):
    """TODO: Docstring for download.

    :local_filename: TODO
    :url: TODO
    :returns: TODO

    """
    download_file_content = requests.get(url).content
    try:
        open(local_filename, "wb").write(download_file_content)
        print(f"download {url} success")
    except Exception as e:
        print(f"{url} download failed!")

def guolv(str_val):
    for k in key_ignore:
        if k in str_val:
            return True
    return False

def guolv_exist_song(song_name):
    if song_name in key_is_exist:
        return True
    return False

def guolv_exist_song_local(song_name):
    if os.path.exists(os.path.join(music_dir, song_name)):
        return True
    return False

class ThreadRun:
    """docstring for ThreadRun"""
    def __init__(self, max_num):
        self.max_num = max_num
        self.create_executor()
        # self.task = task

    def get_executor(self):
        return self.executor

    def create_executor(self):
        # 创建executor
        self.executor = ThreadPoolExecutor(max_workers=self.max_num)


    def run(self, task, *args, **kwargs):
        task = self.executor.submit(task, *args, **kwargs)
        tasks.append(task)

def get_song(song_name, arthor, href):
    print(f"href: {href}")
    key_is_exist.append(song_name)
    mid = get_music_mid(f"https://www.fangpi.net{href}")
    m_download_url = get_music_url(mid)
    print(m_download_url)
    download(local_filename=os.path.join(music_dir, arthor + '-' + song_name + ".mp3"), url=m_download_url)


def get_songs_by_input():
    search_str = input("请输入要下载的歌的原唱或歌名:")
    if not search_str:
        print("搜索的字符不能为空!!!")
        return
    url = f"https://www.fangpi.net/s/{search_str}"

    t = ThreadRun(5)
    html_obj = get_html_obj(url=url)
    ret = get_xpath_list(html_obj, "//div[@class='row']")
    if ret:
        for item in ret:
            href = get_xpath_list(item, ".//@href")[0].strip()
            song_name = get_xpath_list(item, ".//span/span/text()")[0].strip()
            arthor = get_xpath_list(item, ".//small/text()")[0].strip()
            info = {"href": href, "song_name": song_name, "arthor": arthor}
            # print(info)
            print(f"song_name: {song_name}")
            if guolv(song_name) or guolv_exist_song(song_name) or guolv_exist_song_local(arthor + "-" + song_name + ".mp3"):
                print("跳过")
                continue
            t.run(get_song, song_name=song_name, arthor=arthor, href=href)
        wait(tasks)

def init():
    """TODO:
    初始化脚本
    """
    if not os.path.isdir(music_dir):
        os.makedirs(music_dir)


if __name__ == "__main__":
    init()
    get_songs_by_input()


